package tests;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import contracts.ContractException;
import contracts.PreconditionException;

import services.BombeService;

public abstract class AbstractBombeTest {
	private BombeService bombeService;
	
	protected AbstractBombeTest(){
		this.bombeService = null;
	}
	
	protected final BombeService getBombe(){
		return this.bombeService;
	}
	
	protected final void setBombe(BombeService bombeService){
		this.bombeService = bombeService;
	}
	
	@Before
	public abstract void beforeTests();
	
	@After
	public final void afterTests() {
		this.bombeService = null;
	}
	
	/**
	 * Test de l'objectif 1 (numero a verifier)
	 * precondition de init : 3 <= amplitude <= 11
	 * cas de test 1.1 : amplitude < 3
	 * @throws ContractException 
	 */
	@Test(expected=PreconditionException.class)
	public void testInit1() throws ContractException{
		this.bombeService.init(0, 0, 0, 0);
	}
	
	/**
	 * Test de l'objectif 1 (numero a verifier)
	 * precondition de init : 3 <= amplitude <= 11
	 * cas de test 1.2 : amplitude = 3
	 */
	@Test
	public void testInit2(){
		try {
			this.bombeService.init(0, 0, 0, 3);
			assertTrue(true);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 1 (numero a verifier)
	 * precondition de init : 3 <= amplitude <= 11
	 * cas de test 1.3 : amplitude > 3 and amplitude < 11
	 * @throws ContractException 
	 */
	@Test
	public void testInit3(){
		try {
			this.bombeService.init(0, 0, 0, 7);
			assertTrue(true);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 1 (numero a verifier)
	 * precondition de init : 3 <= amplitude <= 11
	 * cas de test 1.4 : amplitude = 11
	 * @throws ContractException 
	 */
	@Test
	public void testInit4(){
		try {
			this.bombeService.init(0, 0, 0, 11);
			assertTrue(true);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 1 (numero a verifier)
	 * precondition de init : 3 <= amplitude <= 11
	 * cas de test 1.5 : amplitude > 11
	 * @throws ContractException 
	 */
	@Test(expected=PreconditionException.class)
	public void testInit5() throws ContractException{
		this.bombeService.init(0, 0, 0, 13);
	}

	/**
	 * Test de l'objectif 2 (numero a verifier)
	 * postcondition de init
	 * cas de test 2.1 : getNumero(init(num, x, y, amplitude)) = num
	 * conditions initiales : 3 <= amplitude <= 11
	 * operation : init(num, x, y, amplitude)
	 * oracle : pas d'exception
	 */
	@Test
	public void testInit6(){
		try {
			this.bombeService.init(3, 0, 0, 7);
			assertTrue(this.bombeService.getNumero() == 3);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 2 (numero a verifier)
	 * postcondition de init
	 * cas de test 2.2 : getX(init(num, x, y, amplitude)) = x
	 * conditions initiales : 3 <= amplitude <= 11
	 * operation : init(num, x, y, amplitude)
	 * oracle : pas d'exception
	 */
	@Test
	public void testInit7(){
		try {
			this.bombeService.init(0, 3, 0, 7);
			assertTrue(this.bombeService.getX() == 3);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 2 (numero a verifier)
	 * postcondition de init
	 * cas de test 2.3 : getY(init(num, x, y, amplitude)) = y
	 * conditions initiales : 3 <= amplitude <= 11
	 * operation : init(num, x, y, amplitude)
	 * oracle : pas d'exception
	 */
	@Test
	public void testInit8(){
		try {
			this.bombeService.init(0, 0, 3, 7);
			assertTrue(this.bombeService.getY() == 3);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 2 (numero a verifier)
	 * postcondition de init
	 * cas de test 2.4 : getAmplitude(init(num, x, y, amplitude)) = amplitude
	 * conditions initiales : 3 <= amplitude <= 11
	 * operation : init(num, x, y, amplitude)
	 * oracle : pas d'exception
	 */
	@Test
	public void testInit9(){
		try {
			this.bombeService.init(0, 0, 0, 7);
			assertTrue(this.bombeService.getAmplitude() == 7);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
	
	/**
	 * Test de l'objectif 2 (numero a verifier)
	 * postcondition de init
	 * cas de test 2.5 : getCompteARebours(init(num, x, y, amplitude)) = 10
	 * conditions initiales : 3 <= amplitude <= 11
	 * operation : init(num, x, y, amplitude)
	 * oracle : pas d'exception
	 */
	@Test
	public void testInit10(){
		try {
			this.bombeService.init(0, 0, 0, 7);
			assertTrue(this.bombeService.getCompteARebours() == 10);
		} catch (ContractException e) {
			Assert.fail("ContractException not expected");
		}
	}
}
